#include <stdint.h>
#include "../libc/string.h"
#include "../libc/mem.h"
#include "../libc/list.h"
#include "../cpu/port.h"
#include "../cpu/page.h"
#include "../driver/screen.h"
#include "../driver/acpi.h"
#include "../driver/pci.h"
#include "../driver/usb.h"
#include "task.h"
#include "kernel.h"

extern uint32_t tick;
extern list_t *pci_list;

static task_t t1;
static task_t t2;
static task_t t3;
static int show1 = 0;
static int show2 = 0;
static int show3 = 0;
static void task1() {
    int count = 1;
    char str[50];
    while (1)
    {
        if(count++ % 100000000 == 0 && show1) {
            int2ascii(count, str);
            kprint("task1: ");
            kprint(str);
            kprint("\n");
        }
    }
}
static void task2() {
    int count = 1;
    char str[50];
    while (1)
    {
        if(count++ % 100000000 == 0 && show2) {
            int2ascii(count, str);
            kprint("task2: ");
            kprint(str);
            kprint("\n");
        }
    }
}
static void task3() {
    int count = 1;
    char str[50];
    while (1)
    {
        if(count++ % 100000000 == 0 && show3) {
            int2ascii(count, str);
            kprint("task3: ");
            kprint(str);
            kprint("\n");
        }
    }
}

void kernel_main() {
    page_dir_t *dir = kmalloc(sizeof(page_dir_t), 1);
    page_tab_t *tab0 = kmalloc(sizeof(page_tab_t), 1);
    page_tab_t *tab1 = kmalloc(sizeof(page_tab_t), 1);

    clear_screen();
    kprint("start kernel!\n");
    

    // acpi关机初始化
    initAcpi();

    // pci初始化
    pci_enumerate();

    // 分页
    // char *p1 = (char *) 0x400000;
    // char *p2 = (char *) 0x500000;
    // char *str1 = "physical addr: 0x400000";
    // char *str2 = "physical addr: 0x500000";
    // memcopy((uint8_t *)str1, (uint8_t *)p1, strlen(str1) + 1);
    // memcopy((uint8_t *)str2, (uint8_t *)p2, strlen(str2) + 1);
    // kprint("before page linear address 0x400000 map to ");
    // kprint(p1);
    // kprint("\n");
    // init_page_dir(dir);
    // init_page_tab(tab0, 0);
    // init_page_tab(tab1, 0x500000);
    // set_page_dir_entry(dir, 0, tab0);
    // set_page_dir_entry(dir, 1, tab1);
    // enable_page(dir);
    // kprint("after page linear address 0x400000 map to ");
    // kprint(p1);
    // kprint("\n");

    // 初始化任务
    // init_task(&t1, task1);
    // init_task(&t2, task2);
    // init_task(&t3, task3);
    // add_task(&t1);
    // add_task(&t2);
    // add_task(&t3);

    // 初始化中断
    isr_install();
    asm volatile("int $0");
    asm volatile("int $1");
    asm volatile("int $2");
    irq_install();

    // 初始化usb
    usb_init();

    while(1);
}

void user_input(char *line) {
    if (strcmp(line, "exit") == 0) {
        kprint("hlt");
        // port_word_out(0x604, 0x2000);
        acpiPowerOff();
    } else if(strcmp(line, "time") == 0) {
        char str[10];
        int2ascii(tick/50, str);
        kprint("running time: ");
        kprint(str);
        kprint("s\n");
    } else if(strcmp(line, "task1 on") == 0) {
        show1 = 1;
    } else if(strcmp(line, "task1 off") == 0) {
        show1 = 0;
    } else if(strcmp(line, "task2 on") == 0) {
        show2 = 1;
    } else if(strcmp(line, "task2 off") == 0) {
        show2 = 0;
    } else if(strcmp(line, "task3 on") == 0) {
        show3 = 1;
    } else if(strcmp(line, "task3 off") == 0) {
        show3 = 0;
    } else if(strcmp(line, "clear") == 0) {
        clear_screen();
    } else {
        kprint("you said: ");
        kprint(line);
        kprint("\n");
    }
    
}
